package xframe.util;

import java.io.File;
import java.io.UnsupportedEncodingException;
import java.util.*;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.fileupload.*;

import xframe.util.beans.UploadFile;
import xframe.util.db.Row;
import xframe.conf.Constants;

// Referenced classes of package xframe.util:
//            FileManager, UtilMaster

public class AutoMapper{
	private List fileItemList;
    private DiskFileUpload fileUpload;
    private ArrayList uploadFileList;
    private HashMap hmParam;

    public ArrayList getFiles()
    {
        return uploadFileList;
    }

    public void destory()
    {
        fileItemList = null;
        fileUpload = null;
        uploadFileList = new ArrayList();
        hmParam = new HashMap();
    }
    /**
     * @see  : Multipart를 처리하기 위해 구현된 함수로 내부 접근 함수를 통해서 hashmap으로 받을 수 있다.
     * 예>  AutoMapper mapper = new AutoMapper(request, savePath,sizeLimit, "euc-kr", Constant.UPLOAD_currentTimeMillis_NAME_RULE);
     * @param request  : HttpServletRequest
     * @param savePath  : 파일이 저장될 위치
     * @param sizeLimit  : 파일의 제한용량 byte 기준(1024*10*10=>10Mb)가된다.
     * @param encoding  :인코딩하고자 하는 값을 넣는다.
     * @param request  : HttpServletRequest
     * @param request  : HttpServletRequest
     * @return :  생성자 함수
     */
    public AutoMapper(HttpServletRequest request, String savePath, int sizeLimit, String encoding, int UPLAOD_FILE_RULE)
        throws Exception
    {
        fileItemList = null;
        fileUpload = null;
        uploadFileList = new ArrayList();
        hmParam = new HashMap();
        if(FileUploadBase.isMultipartContent(request))
        {
            fileUpload = new DiskFileUpload();
            fileUpload.setHeaderEncoding(encoding);
            fileUpload.setRepositoryPath(savePath);
            fileUpload.setSizeMax(sizeLimit);
            fileUpload.setSizeThreshold(1024*50);
            String fileRename = "";
            try
            {/* FileItem의 리스트 */
                fileItemList = fileUpload.parseRequest(request);
                for(int i = 0; i < fileItemList.size(); i++)
                {
                    FileItem fileItem = (FileItem)fileItemList.get(i);
                    if(!fileItem.isFormField())
//                    	 파일일때,
                        if(fileItem.getSize() > 0)
                        {
                            String fileNameExe = fileItem.getName().substring(fileItem.getName().lastIndexOf("\\") + 1);
                            String purefileName = "";
                            if(fileNameExe.indexOf(".") > 0)
                                purefileName = fileNameExe.substring(0, fileNameExe.lastIndexOf("."));
                            else
                                purefileName = fileNameExe;
                            String fileName = "";
                            String exe = "";
                            String dot = ".";
                            if(fileNameExe.lastIndexOf('.') != -1)
                            {
                                fileName = purefileName;
                                exe = fileNameExe.substring(fileNameExe.lastIndexOf('.') + 1);
                                dot = ".";
                            } else
                            {
                                fileName = fileNameExe;
                                dot = "";
                            }
                            try
                            {
                                if(UPLAOD_FILE_RULE == Constants.UPLOAD_REAL_NAME_RULE){
                                    //파일명 그대로 업로드 할때
                                    //저장된 파일 정보를 UploadFile 객체에 담는다.
                                    uploadFileList.add(new UploadFile(fileNameExe, fileNameExe, fileItem.getSize(), savePath));
                                    //서버에 파일 저장
                                    fileItem.write(new File(savePath, fileNameExe));
                                } else if(UPLAOD_FILE_RULE == Constants.UPLOAD_REAL_SEQ_NAME_RULE){
                                	//저장된 파일 정보를 UploadFile 객체에 담는다.		
                                    fileRename = FileManager.getFileRename(savePath, fileNameExe, 0);
                                    uploadFileList.add(new UploadFile(fileNameExe, fileRename, fileItem.getSize(), savePath));
                                    //서버에 파일 저장	
                                    fileItem.write(new File(savePath, fileRename));
                                } else if(UPLAOD_FILE_RULE == Constants.UPLOAD_currentTimeMillis_NAME_RULE){
                                	//저장된 파일 정보를 UploadFile 객체에 담는다.
                                    uploadFileList.add(new UploadFile(fileNameExe, fileName + System.currentTimeMillis() + dot + exe, fileItem.getSize(), savePath));
                                    //서버에 파일 저장
                                    fileItem.write(new File(savePath, FileManager.getFileRename(savePath, fileName + System.currentTimeMillis() + dot + exe, 0)));
                                }
                            }catch(Exception e){
                                throw e;
                            }
                        } else{
                        	 System.out.println("The File size '0'.");
                        }
                }

            }
            catch(FileUploadException e)
            {
                e.printStackTrace();
            }
        } else{
            System.out.println("Only 'enctype=\"multipart/form-data\"' permmit here! ");
        }
    }
    /**
     * @see  : Multipart를 처리하기 위해 구현된 함수로 내부 접근 함수를 통해서 hashmap으로 받을 수 있다.
     * 예>  AutoMapper mapper = new AutoMapper(request, savePath,sizeLimit, "euc-kr", Constant.UPLOAD_currentTimeMillis_NAME_RULE);
     * @param request  : HttpServletRequest
     * @param savePath  : 파일이 저장될 위치
     * @param pathPlus  : 파일이 저장될 위치의  sub 디렉토리명
     * @param sizeLimit  : 파일의 제한용량 byte 기준(1024*10*10=>10Mb)가된다.
     * @param encoding  :인코딩하고자 하는 값을 넣는다.
     * @param request  : HttpServletRequest
     * @param request  : HttpServletRequest
     * @return :  생성자 함수
     */    

    public AutoMapper(HttpServletRequest request, String savePath, String pathPlus, int sizeLimit, int UPLAOD_FILE_RULE)
        throws FileUploadException    {
        fileItemList = null;
        fileUpload = null;
        uploadFileList = new ArrayList();
        hmParam = new HashMap();
        if(FileUploadBase.isMultipartContent(request))
        {
            fileUpload = new DiskFileUpload();
            fileUpload.setHeaderEncoding("utf-8");
            fileUpload.setRepositoryPath(savePath);
            fileUpload.setSizeMax(sizeLimit);
            fileUpload.setSizeThreshold(1024*50);
            String fileRename = "";
            fileItemList = fileUpload.parseRequest(request);
            if(getMutlpartParam().get(pathPlus) != null){
            	savePath = savePath + "/" + getMutlpartParam().get(pathPlus);
            }else{
            	savePath = savePath + "/" + pathPlus;
            }
            for(int i = 0; i < fileItemList.size(); i++){
                FileItem fileItem = (FileItem)fileItemList.get(i);
                if(!fileItem.isFormField())
                    if(fileItem.getSize() > 0L)
                    {
                        String fileNameExe = fileItem.getName().substring(fileItem.getName().lastIndexOf("\\") + 1);
                        String purefileName = "";
                        if(fileNameExe.indexOf(".") > 0)
                            purefileName = fileNameExe.substring(0, fileNameExe.lastIndexOf("."));
                        else
                            purefileName = fileNameExe;
                        String fileName = "";
                        String exe = "";
                        String dot = ".";
                        if(fileNameExe.lastIndexOf('.') != -1)
                        {
                            fileName = purefileName;
                            exe = fileNameExe.substring(fileNameExe.lastIndexOf('.') + 1);
                            dot = ".";
                        } else
                        {
                            fileName = fileNameExe;
                            dot = "";
                        }
                        try{ 
                        	/* FileItem의 리스트 */
                            if(UPLAOD_FILE_RULE == Constants.UPLOAD_REAL_NAME_RULE)
                            {
                                uploadFileList.add(new UploadFile(fileNameExe, fileNameExe, fileItem.getSize(), savePath));
                                fileItem.write(new File(savePath, fileNameExe));
                            } else if(UPLAOD_FILE_RULE == Constants.UPLOAD_REAL_SEQ_NAME_RULE ) {
                                fileRename = FileManager.getFileRename(savePath, fileNameExe, 0);
                                uploadFileList.add(new UploadFile(fileNameExe, fileRename, fileItem.getSize(), savePath));
                                fileItem.write(new File(savePath, fileRename));
                            } else if(UPLAOD_FILE_RULE == Constants.UPLOAD_currentTimeMillis_NAME_RULE){
                                uploadFileList.add(new UploadFile(fileNameExe, fileName + System.currentTimeMillis() + dot + exe, fileItem.getSize(), savePath));
                                fileItem.write(new File(savePath, FileManager.getFileRename(savePath, fileName + System.currentTimeMillis() + dot + exe, 0)));
                            }else if(UPLAOD_FILE_RULE == Constants.UPLOAD_currentTimeMillis_NAME_RULE_COPY){
                                uploadFileList.add(new UploadFile(fileNameExe, fileName + System.currentTimeMillis() + dot + exe, fileItem.getSize(), savePath+"/org/"));
                                long fileNameSuffix = System.currentTimeMillis();
                                fileItem.write(new File(savePath, FileManager.getFileRename(savePath, fileName + fileNameSuffix + dot + exe, 0)));
                                
                                
                                File checkOrgFolder = new File(savePath+"/org/");;
    							if(!checkOrgFolder.exists()){
    								System.out.println("'org' Folder is not exist!");
    								System.out.println("make org folder ["+checkOrgFolder.getAbsolutePath()+"]:"+checkOrgFolder.mkdir());
    							}
                                FileManager.CopyFile(savePath+"/"+fileName + fileNameSuffix + dot + exe, savePath+"/org/"+fileName + fileNameSuffix + dot + exe);
                            }
                            
                        }catch(Exception e){
                            e.printStackTrace();
                        }
                    } else{
                    	System.out.println("The File size '0'.");
                    }
            }

        } else{
        	System.out.println("Only 'enctype=\"multipart/form-data\"' permmit here! ");
        }
    }
    /**
     * @see  : Multipart로 넘겨진 파라미터의 값을 추출할때 사용하는 함수
     * @param fileItemList  : 생성자로 만들어진 List에는 Multipart로 넘겨진 파일 정보가 담겨져 있다.
     * @param parmName  : 파라미터 명
     * @return   FileItem :  파일정보를 return 한다.
     */  

    public FileItem getParameter2FileItem(List fileItemList, String parmName)
    {
        for(int i = 0; i < fileItemList.size(); i++)
        {
            FileItem fileItem = (FileItem)fileItemList.get(i);
            if(fileItem.getFieldName().equals(parmName))
                return fileItem;
        }

        return null;
    }

    /**
     * @see  : 넘겨진 파라미터의 값을 추출할때 사용하는 함수
     * @param fileItemList  : 생성자로 만들어진 List에는 Multipart로 넘겨진 파일 정보가 담겨져 있다.
     * @param parmName  : 파라미터 명
     * @return   String :  파라미터 값을 return 한다.
     */  

    public String getParameter(List fileItemList, String parmName)
    {
        FileItem fileItem = null;
        for(int i = 0; i < fileItemList.size(); i++)
        {
            fileItem = (FileItem)fileItemList.get(i);
            if(fileItem.getFieldName().trim().equals(parmName))
                return fileItem.getString();
        }

        return null;
    }

    /**
     * @see  : 넘겨진 Multipart 로 넘겨진 파라미터의 값을 추출할때 사용하는 함수
     * @return   String :  파라미터 값이 담긴 Map을 리턴 한다.
     */  
    public Row getMutlpartParam()
    {
        HashMap hmCnt = new HashMap();
        Row retrunHm = new Row();
        FileItem fileItem = null;
        ArrayList list = null;
        int indexCnt = 0;
        int idx = 0;
        for(int i = 0; i < fileItemList.size(); i++)
        {
            fileItem = (FileItem)fileItemList.get(i);
            if(!hmCnt.isEmpty() && hmCnt.containsKey(fileItem.getFieldName()))
            {
                //입력받은 파라미터의 중복을 확인한다.
                //그래서 중복여부로 단일값인지 여러 동일한 중복 파라미터인지 확인하여 갯수를 체크한다.
            	
                indexCnt = Integer.parseInt((String)hmCnt.get(fileItem.getFieldName()));
                indexCnt++;
                //해당객체를 빼서 넘어온 값을 받아서 다시 넣어준다.
                
                if(!fileItem.isFormField())
                {
                    if(fileItem.getSize() > 0)
                    {
                        idx = fileItem.getName().lastIndexOf("\\");
                        if(idx == -1)
                            idx = fileItem.getName().lastIndexOf("/");
                        list = (ArrayList)hmParam.get(fileItem.getFieldName());
                        list.add(fileItem.getName().substring(idx + 1));
                        hmCnt.put(fileItem.getFieldName(), (new StringBuffer(String.valueOf(indexCnt))).toString());
                        hmParam.put(fileItem.getFieldName(), list);
                    }
                } else
                {
                    list = (ArrayList)hmParam.get(fileItem.getFieldName());
                    list.add(fileItem.getString());
                    hmCnt.put(fileItem.getFieldName(), (new StringBuffer(String.valueOf(indexCnt))).toString());
                    hmParam.put(fileItem.getFieldName(), list);
                }
            } else
            	//중복된 필드가 없을떼
            if(!fileItem.isFormField()){
            	//file 일떼
                if(fileItem.getSize() > 0){
                	//파일이 0 보다 사이즈가 클때, 즉 파일이 선택되어 넘어 왔을떼
                    list = new ArrayList();
                    idx = fileItem.getName().lastIndexOf("\\");
                    if(idx == -1)
                        idx = fileItem.getName().lastIndexOf("/");
                    hmCnt.put(fileItem.getFieldName(), "0");
                    list.add(0, fileItem.getName().substring(idx + 1));
                    hmParam.put(fileItem.getFieldName(), list);
                }
            } else{
            	//input type이 파일이 아닐떼
                list = new ArrayList();
                hmCnt.put(fileItem.getFieldName(), "0");
                list.add(0, fileItem.getString());
                hmParam.put(fileItem.getFieldName(), list);
            }
        }

        retrunHm = setMultiHash(hmParam);
        return retrunHm;
    }

    /**
     * @see  : 넘겨진 파라미터 값이 multi row 형태로 작업이 진행될때, 
     * @param hmParam; 
     * @return   String :  파라미터 값이 담긴 Map을 리턴 한다.
     */  

    private Row setMultiHash(HashMap hmParam)
    {
        ArrayList List = null;
        String data[] = null;
        String indexKeys[] = UtilMaster.getHashKeys(hmParam);
        Row hm = new Row();
        for(int i = 0; i < indexKeys.length; i++)
        {
            List = (ArrayList)hmParam.get(indexKeys[i]);
            data = new String[List.size()];
            for(int j = 0; j < List.size(); j++)
                data[j] = (String)List.get(j);

            if(data.length > 1)
                hm.put(indexKeys[i], data);
            else
                hm.put(indexKeys[i], data[0]);
        }

        return hm;
    }

    /**
     * @see  : 넘겨진 파라미터 값이 multi row 형태로 작업이 진행될때, 
     * @param hmParam; 
     * @return   String :  파라미터 값이 담긴 Map을 리턴 한다.
     */ 
    public static void setRequestParam(HttpServletRequest request)
    {
        setAttribues(request, getRequest(request));
    }

    public static void setAttribues(HttpServletRequest request, Row hm)
    {
        String para_name[] = UtilMaster.getHashKeys(hm);
        for(int i = 0; i < hm.size(); i++){
        	//try {
				//charSet((String)hm.get(para_name[i]));
			//} catch (UnsupportedEncodingException e) {
			//	e.printStackTrace();
			//}
            request.setAttribute(para_name[i], hm.get(para_name[i]));
        }

    }
    public static void charSet(String str_kr) throws UnsupportedEncodingException{
        String charset[] = {"euc-kr", "ksc5601", "iso-8859-1", "8859_1", "ascii", "UTF-8"};
            
        for(int i=0; i<charset.length ; i++){
            for(int j=0 ; j<charset.length ; j++){
                if(i==j) continue;

       //System.out.println("AutoMapper :"+charset[i]+" : "+charset[j]+" :"+new String(str_kr.getBytes(charset[i]),charset[j]));
            }
        }
    }

    public static HashMap getAttribues(HttpServletRequest request)
    {
        HashMap hm = new HashMap();
        String paramName;
        for(Enumeration e = request.getAttributeNames(); e.hasMoreElements(); hm.put(paramName, request.getAttribute(paramName)))
            paramName = (String)e.nextElement();

        return hm;
    }

    public static Row getRequest(HttpServletRequest request){
        String  encordingFrom ="";
        String  encordingTo ="";
        String encordingStr = "";
        boolean encoding = false;
    	try {
    		encoding	=	"true".equalsIgnoreCase(UtilMaster.null2Default(DynamicVar.get("xframe.parameter.encoding"),"false"));
    		if(encoding){
			encordingFrom = DynamicVar.get("xframe.parameter.encoding.from");
			encordingTo = DynamicVar.get("xframe.parameter.encoding.to");
    		}
		} catch (XMLQueryException e1) {
			e1.printStackTrace();
		} 
    	
    	String param_string ="";
    	
        Row row = new Row();
        for(Enumeration enumr = request.getParameterNames(); enumr.hasMoreElements();){
            String key = (String)enumr.nextElement();
            String value[] = request.getParameterValues(key);
            if(value.length == 1){
            	param_string	=	request.getParameter(key);
            	if(encoding){
	            	try {
	            		if(param_string != null){
	        				encordingStr = new String(param_string.getBytes(encordingFrom),encordingTo);
	        			}
					} catch (UnsupportedEncodingException e) {
						e.printStackTrace();
					}
            	}else{
            		encordingStr = param_string;
            	}
                row.put(key, encordingStr);
            }else  if(value.length > 1){
            	for(int i = 0 ; i < value.length ; i++){
            		if(encoding){
	            		if(value[i] != null){
	            			try {
								value[i] = new String(value[i].getBytes(encordingFrom),encordingTo);
							} catch (UnsupportedEncodingException e) {
								e.printStackTrace();
							}
	        			}
            		}
            		row.put(key, value);
            	}
                
            }
        }

        return row;
    }

    
}
